home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
filesyst
/
dosfs
/
dmsdosfs.000
/
dmsdosfs
/
dmsdosfs-0.6.9b
/
dmsdos_fixdir.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-29
|
4KB
|
146 lines
/*
dmsdos_fixdir.c
fixes directory problems under win95 drivespace 3
this code actually rearranges shortened directory clusters to avoid
problems with an inode-oriented filesystem
******************************************************************************
DMSDOS (Doublespace/Drivespace compressed MSDOS filesystem) for Linux
written 1995,1996 by Frank Gockel
(C) Copyright 1995,1996 by Frank Gockel
Some code of the dmsdos filesystem has been copied from the msdos filesystem
so there are the following additional copyrights:
(C) Copyright 1992,1993 by Werner Almesberger (msdos filesystem)
(C) Copyright 1994,1995 by Jacques Gelinas (mmap code)
(C) Copyright 1992-1995 by Linus Torvalds
The DMSDOS filesystem was inspired by the THS filesystem (a simple doublespace
DS-0-2 compressed read-only filesystem) written 1994 by Thomas Scheuermann.
The DMSDOS filesystem is distributed under the Gnu General Public Licence.
See file COPYING for details.
******************************************************************************
*/
#include<linux/fs.h>
#include<linux/msdos_fs.h>
#include<linux/malloc.h>
#include<linux/dmsdos_fs.h>
extern Dblsb dblsb[];
int fix_cluster_length(struct super_block*sb,int cvfnr,int clusternr,int*count)
{ Mdfat_entry mde;
unsigned char * clusterd;
int i;
int membytes;
dbl_mdfat_value(sb,clusternr,cvfnr,NULL,&mde);
if(mde.size_lo_minus_1+1<dblsb[cvfnr].s_sectperclust)
{ printk("DMSDOS: fixdir: fixing cluster %d cvfnr%d\n",clusternr,cvfnr+1);
membytes=dblsb[cvfnr].s_sectperclust*SECTOR_SIZE;
clusterd=(unsigned char*)MALLOC(membytes);
if(clusterd==NULL)
{ printk("DMSDOS: fixdir: no memory, aborting!\n");
return -1;
}
if(dmsdos_read_cluster(sb,clusterd,clusternr,cvfnr)<0)
{ printk("DMSDOS: fixdir: read_cluster %d in CVF %d failed, aborting!\n",
clusternr,cvfnr+1);
FREE(clusterd);
return -1;
}
for(i=(mde.size_hi_minus_1+1)*SECTOR_SIZE;i<membytes;++i)clusterd[i]=0;
if(dmsdos_write_cluster(sb,clusterd,membytes,clusternr,0,cvfnr,1)<0)
{ printk("DMSDOS: fixdir: write_cluster %d in CVF %d failed, aborting!\n",
clusternr,cvfnr+1);
FREE(clusterd);
return -1;
}
FREE(clusterd);
++(*count);
return 0;
}
return 0;
}
/* hmmm... I got mail that this recursive function may run out of stack space
-- cannot imagine -- it doesn't use at least 100 bytes stack --
so I added the MAXDEPTH check to avoid endless recursion in case of some
strange failures
*/
#define MAXDEPTH 10
int fixdir_u(struct super_block*sb,int dirstartclust, int cvfnr,int depth,
int*count)
{ int entrynr;
unsigned char buf[32];
int subdirclust,clust;
unsigned char * pp;
/* don't allow endless recursion in case of unknown failures */
if(depth>MAXDEPTH)
{ printk("DMSDOS: fixdir: depth > MAXDEPTH, won't go deeper (cluster=%d cvfnr=%d).\n",
dirstartclust,cvfnr+1);
return 0; /* don't abort */
}
clust=dirstartclust;
do
{ if(fix_cluster_length(sb,cvfnr,clust,count)<0)return -1;
clust=dbl_fat_nextcluster(sb,clust,cvfnr,NULL);
}
while(clust>0);
entrynr=2; /* don't go through '.' and '..' */
while(read_dbl_direntry(sb,dirstartclust,cvfnr,entrynr++,buf)>0)
{ if(buf[0]!=0&&buf[0]!=0xe5&&((buf[11]&0xF0)==0x10))
{ pp=&(buf[26]);
subdirclust=CHS(pp);
if(subdirclust>0)
{ if(fixdir_u(sb,subdirclust,cvfnr,depth+1,count)<0)return -1;
}
}
}
return 0;
}
int fixdir(struct super_block* sb,int cvfnr)
{ int entrynr;
unsigned char buf[32];
int subdirclust;
unsigned char * pp;
int count=0;
printk("DMSDOS: fixdir: scanning directories of CVF %d...\n",cvfnr+1);
entrynr=0;
while(read_dbl_direntry(sb,0,cvfnr,entrynr++,buf)>0)
{ if(buf[0]!=0&&buf[0]!=0xe5&&((buf[11]&0xF0)==0x10))
{ pp=&(buf[26]);
subdirclust=CHS(pp);
if(subdirclust>0)
{ if(fixdir_u(sb,subdirclust,cvfnr,0,&count)<0)
{ if(count)printk("DMSDOS: fixdir: aborted after rearranging %d directory clusters successfully.\n",count);
else printk("DMSDOS: fixdir: aborted - no rearrangements done.\n");
return -1;
}
}
}
}
if(count)printk("DMSDOS: fixdir: %d directory clusters successfully rearranged.\n",
count);
else printk("DMSDOS: fixdir: no rearrangements necessary.\n");
return 0;
}